/*
 * @Author: JohnYang
 * @Date: 2020-10-24 17:37:30
 * @LastEditors: JohnYang
 * @LastEditTime: 2020-11-07 16:52:42
 */

import Vue from 'vue'
import Component from 'vue-class-component'
import { Inject, Prop } from 'vue-property-decorator'
import RadioGroup from './components/radio-group'
import ComboxControl from './components/combox-control'
import Raw from './components/raw'
@Component({
  name: 'FormControl',
  components: {
    RadioGroup,
    Raw,
    ComboxControl,
  },
})
export default class FormControl extends Vue {
  @Prop({
    required: true,
  })
  value

  get prop() {
    return this.$attrs.prop
  }

  @Inject('form')
  form

  options = []

  setValue(value) {
    this.form.$emit('set-value', {
      prop: this.prop,
      value,
    })
    return this
  }

  setAttrs(attrs) {
    this.form.$emit('set-attrs', {
      prop: this.prop,
      attrs,
    })
    return this
  }

  genSlots(slots) {
    return Object.entries(slots).map(([prop, func]) => {
      var vnode = typeof func === 'function' ? func(this.$createElement) : null
      return vnode && <template slot={prop}>{vnode}</template>
    })
  }

  render(h) {
    var { tag, style, getDataList, transformRule, slots, ...rest } = this.$attrs
    var tagName = ''
    if (tag == 'el-radio-group') {
      tag = 'RadioGroup'
    } else if (['span', 'div', 'a', 'p'].includes(tag)) {
      tagName = tag
      tag = 'Raw'
    } else if (tag === 'el-select') {
      tag = 'combox-control'
      rest.type = 'select'
    }
    var options =
      typeof getDataList === 'function' ? this.options : rest.options
    return h(
      tag,
      {
        props: {
          ...rest,
          value: this.value,
          options: options,
        },
        attrs: {
          ...rest,
          options: options,
          tagName,
        },
        on: {
          ...this.$listeners,
          input: (val) => {
            var dist =
              typeof transformRule === 'function' ? transformRule(val) : val
            this.$emit('input', dist)
          },
        },
        scopedSlots: {
          ...this.$scopedSlots,
        },
      },
      this.genSlots(slots || {})
    )
  }

  async reloadControl() {
    var { prop, getDataList } = this.$attrs
    if (typeof getDataList !== 'function') {
      return
    }
    let resp = await getDataList(this.form.model[prop], this.form.model)
    if (Array.isArray(resp)) {
      this.options = resp
    }
  }

  mounted() {
    var { prop } = this.$attrs
    this.form.$emit('ready', prop, this)
    this.reloadControl()
  }
}
